package game;

import java.util.ArrayList;
import java.util.List;

import tree.*;

/**
 * Solver to solve 24-Game.
 * @author Natchanon Hongladaromp
 *
 */
public class Solver
{
	private static Solver instance;
	
	/**
	 * Returns instance.
	 * @return instance
	 */
	public static Solver getInstance()
	{
		if(instance == null)
			instance = new Solver();
		return instance;
	}
	
	/**
	 * Solve 4 number
	 * @param numbers
	 * @return answer
	 */
	public String gameSolve(int... numbers)
	{
		List<Tree> A = new ArrayList<Tree>();

		for (int n : numbers)
		{
			A.add(new NumberNode(n));
		}

		Tree r = findSolution(A);
		if (r != null)
			return r.toString();
		else
			return "no solution";
	}

	/**
	 * Recursion method.
	 * @param A List of numbers.
	 * @return answer
	 */
	private Tree findSolution(List<Tree> A)
	{
		if (A.size() == 1 && A.get(0).value() == 24)
			return A.get(0);
		else if (A.size() == 1)
			return null;
		else
		{
			for (int i = 0; i < A.size() - 1; i++)
			{
				for (int j = i + 1; j < A.size(); j++)
				{
					Tree a = A.get(i);
					Tree b = A.get(j);

					ArrayList<Tree> B = new ArrayList<Tree>(A);

					B.remove(a);
					B.remove(b);

					Tree[] temp = new Tree[6];
					temp[0] = new AddNode(a, b);
					temp[1] = new SubtractNode(a, b);
					temp[2] = new SubtractNode(b, a);
					temp[3] = new MultiplyNode(a, b);
					if (b.value() != 0)
						temp[4] = new DivideNode(a, b);
					if (a.value() != 0)
						temp[5] = new DivideNode(b, a);

					for (Tree t : temp)
					{
						if (t == null)
							continue;
						B.add(t);
						Tree r = findSolution(B);
						if (r != null)
						{
							return r;
						}
						B.remove(t);
					}
				}
			}
		}
		return null;
	}
}
